#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hs/hs.h>

#define CHUNK_SIZE 4096

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx);

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Usage: %s <pattern> <file>\n", argv[0]);
        return 1;
    }

    // 正则表达式
    const char *pattern = argv[1];

    // 编译正则表达式
    hs_database_t *database = NULL;
    hs_compile_error_t *compile_err = NULL;
    hs_error_t err = hs_compile(pattern, HS_FLAG_CASELESS, HS_MODE_BLOCK,
                                NULL, &database, &compile_err);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "Error compiling pattern: %s\n",
                compile_err->message);
        hs_free_compile_error(compile_err);
        return 1;
    }

    // 分配临时空间(指针必须初始化为NULL)
    hs_scratch_t *scratch = NULL;
    err = hs_alloc_scratch(database, &scratch);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "Error allocating scratch space\n");
        hs_free_database(database);
        return 1;
    }

    // 处理命令行参数中指定的文件
    const char *filename = argv[2];
    FILE *file = fopen(filename, "r");
    if (!file) {
        fprintf(stderr, "Error opening file %s\n", filename);
        hs_free_scratch(scratch);
        hs_free_database(database);
        return 1;
    }

    // 逐块读入并在每块中进行匹配
    char chunk[CHUNK_SIZE];
    size_t read_size;
    do {
        read_size = fread(chunk, 1, CHUNK_SIZE, file);
        if (read_size > 0) {
            // 单模+块匹配
            err = hs_scan(database, chunk, read_size, 0, scratch,
                          on_match, chunk);
            if (err != HS_SUCCESS) {
                fprintf(stderr, "Error scanning chunk\n");
                hs_free_scratch(scratch);
                hs_free_database(database);
                fclose(file);
                return 1;
            }
        }
    } while (read_size == CHUNK_SIZE);

    // 释放空间
    fclose(file);
    hs_free_scratch(scratch);
    hs_free_database(database);

    return 0;
}

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx)
{
    char *tmp = (char*)ctx;

    printf("Match found at end offset %llu of\n%s\n", to, tmp);

    return 0;
}
